/*
 * Copyright (c) 2019 - 2020 IoT Company of Midea Group.
 *
 * File Name 	    : mcntl_cjson.h
 * Description	    :
 *
 * Version	        : v0.0.1
 * Author			: yexb
 * Date	            : 2021/09/28  msmart4.0
 * History	        :
 */

#ifndef __MCNTL_CJSON_H__
#define __MCNTL_CJSON_H__

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#if __GNUC__ >= 4
#define MS_LAYER_EXPORT __attribute__((visibility("default")))
#else
#define MS_LAYER_EXPORT
#endif

#include "cJSON.h"

typedef cJSON mcntl_cjson;

#define mcntl_cjson_create_object cJSON_CreateObject
#define mcntl_cjson_create_array cJSON_CreateArray
#define mcntl_cjson_add_item_to_object(object, name, i) cJSON_AddItemToObjectCS(object, name, i)
#define mcntl_cjson_detach_item_from_object(object, i) cJSON_DetachItemViaPointer(object, i)
#define mcntl_cjson_add_item_to_array(array, i) cJSON_AddItemToArray(array, i)

#define mcntl_cjson_create_int_array(numbers, count) cJSON_CreateIntArray(numbers, count)
#define mcntl_cjson_create_float_array(numbers, count) cJSON_CreateFloatArray(numbers, count)
#define mcntl_cjson_create_double_array(numbers, count) cJSON_CreateDoubleArray(numbers, count)
#define mcntl_cjson_create_string_array(strings, count) cJSON_CreateStringArray(strings, count)

#define mcntl_cjson_add_null_to_object(object, name) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateNull())
#define mcntl_cjson_add_true_to_object(object, name) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateTrue())
#define mcntl_cjson_add_false_to_object(object, name) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateFalse())
#define mcntl_cjson_add_bool_to_object(object, name, b) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateBool(b))
#define mcntl_cjson_add_number_to_object(object, name, n) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateNumber(n))
#define mcntl_cjson_add_string_to_object(object, name, s) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateString(s))
#define mcntl_cjson_add_string_to_object_not_cs(object, name, i) cJSON_AddStringToObject(object, name, i)
#define mcntl_cjson_add_raw_to_object(object, name, s) mcntl_cjson_add_item_to_object(object, name, cJSON_CreateRaw(s))
#define mcntl_cjson_add_object_to_object cJSON_AddObjectToObject

#define mcntl_cjson_add_null_to_array(array) mcntl_cjson_add_item_to_array(array, cJSON_CreateNull())
#define mcntl_cjson_add_true_to_array(array) mcntl_cjson_add_item_to_array(array, cJSON_CreateTrue())
#define mcntl_cjson_add_false_to_array(array) mcntl_cjson_add_item_to_array(array, cJSON_CreateFalse())
#define mcntl_cjson_add_bool_to_array(array, b) mcntl_cjson_add_item_to_array(array, cJSON_CreateBool(b))
#define mcntl_cjson_add_number_to_array(array, n) mcntl_cjson_add_item_to_array(array, cJSON_CreateNumber(n))
#define mcntl_cjson_add_string_to_array(array, s) mcntl_cjson_add_item_to_array(array, cJSON_CreateString(s))
#define mcntl_cjson_add_raw_to_array(array, s) mcntl_cjson_add_item_to_array(array, cJSON_CreateRaw(s))

#define mcntl_cjson_object_is_null(object) cJSON_IsNull(object)
#define mcntl_cjson_object_is_bool(object) cJSON_IsBool(object)
#define mcntl_cjson_object_is_number(object) cJSON_IsNumber(object)
#define mcntl_cjson_object_is_string(object) cJSON_IsString(object)
#define mcntl_cjson_object_is_array(object) cJSON_IsArray(object)

#define mcntl_cjson_set_string_of_object(object, s) cJSON_SetValuestring(object, s)
#define mcntl_cjson_set_number_of_object(object, n) cJSON_SetNumberHelper(object, n)
#define mcntl_cjson_object_for_each(element, object) for (element = (object != NULL) ? (object)->child : NULL; element != NULL; element = element->next)
#define mcntl_cjson_object_get_name(element) (element->string)

#define mcntl_cjson_array_for_each(element, array) cJSON_ArrayForEach(element, array)

#define mcntl_cjson_get_object_item cJSON_GetObjectItem

#define mcntl_cjson_get_array_item cJSON_GetArrayItem

#define mcntl_cjson_get_array_num cJSON_GetArraySize

#define mcntl_cjson_free cJSON_free

#define mcntl_cjson_version cJSON_Version

#define mcntl_cjson_DeleteItemFromArray cJSON_DeleteItemFromArray

// defaultly cJSON_Parse parse buffer start with '{' and return after '}'
// do not require null terminated
#define mcntl_cjson_parse(str, len) cJSON_Parse(str)

#define mcntl_cjson_get_error_position cJSON_GetErrorPtr

//#define NDEBUG

#ifdef NDEBUG
#define mcntl_cjson_print cJSON_PrintUnformatted
#else
// #define mcntl_cjson_print cJSON_Print
#define mcntl_cjson_print cJSON_Print
#endif

#define mcntl_cjson_print_no_space cJSON_PrintUnformatted

#define mcntl_cjson_delete cJSON_Delete

#define mcntl_cjson_duplicate cJSON_Duplicate

#define mcntl_cjson_minify cJSON_Minify

unsigned int mcntl_cjson_calculate_size(mcntl_cjson* item);
char* mcntl_cjson_get_string_value(const mcntl_cjson* const item);
double mcntl_cjson_get_number_value(const mcntl_cjson* const item);
mcntl_cjson* mcntl_cjson_get_object_item_recursive(mcntl_cjson* item, const char* name);
bool mcntl_cjson_get_bool_value(const mcntl_cjson* const item);

#define mcntl_cjson_ReplaceItemInObjectCaseSensitive(object, name, new_object) cJSON_ReplaceItemInObjectCaseSensitive(object, name, new_object)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif //__MCNTL_CJSON_H__
